#include <stdio.h>

#include "parsetree.h"


//
// constructors
//

ParseTree::ParseTree()
{
}


ParseTree::ParseTree(enum ParseTreeType t, ParseTree *l, ParseTree *r)
    : TreeType(t), Left(l), Right(r), Up(NULL)
{
    if (Left != NULL)
        Left->Up = this;

    if (Right != NULL)
        Right->Up = this;
}


ParseTree::ParseTree(enum ParseTreeType t, ParseTree *a, ParseTree *b, ParseTree *c)
    : TreeType(t), Left(a), Up(NULL)
{
    Right = new ParseTree(PTTArg, b, c);

    if (Left != NULL)
        Left->Up = this;

    Right->Up = this;
}


ParseTree::ParseTree(enum ParseTreeType t, ParseTree *a, ParseTree *b, ParseTree *c, ParseTree *d)
    : TreeType(t), Left(a), Up(NULL)
{
    Right = new ParseTree(PTTArg, b, c, d);

    if (Left != NULL)
        Left->Up = this;

    Right->Up = this;
}



//
// dump the tree for diagnostic purposes
//

void ParseTree::Dump(int Level)
{
    int Count;

    // indent
    for (Count = 0; Count < Level; Count++)
        printf(" ");
    
    // describe this node
    switch (TreeType)
    {
    case PTTNoop:               printf("no-op"); break;
    case PTTArray:              printf("array"); break;
    case PTTAdd:                printf("+"); break;
    case PTTAddAssign:          printf("+="); break;
    case PTTAddressOf:          printf("addressof"); break;
    case PTTArg:                printf("arg"); break;
    case PTTArrow:              printf("->"); break;
    case PTTAssign:             printf("=="); break;
    case PTTBitwiseAnd:         printf("&"); break;
    case PTTBitwiseAndAssign:   printf("&="); break;
    case PTTBitwiseNot:         printf("~"); break;
    case PTTBitwiseOr:          printf("|"); break;
    case PTTBitwiseOrAssign:    printf("|="); break;
    case PTTBitwiseXor:         printf("^"); break;
    case PTTBitwiseXorAssign:   printf("^="); break;
    case PTTBlock:              printf("block"); break;
    case PTTBreak:              printf("break"); break;
    case PTTCase:               printf("case"); break;
    case PTTCast:               printf("cast"); break;
    case PTTContinue:           printf("continue"); break;
    case PTTDereference:        printf("dereference"); break;
    case PTTDesignatorIndex:    printf("designator index"); break;
    case PTTDesignatorMember:   printf("designator member"); break;
    case PTTDivide:             printf("/"); break;
    case PTTDivideAssign:       printf("/="); break;
    case PTTDoWhile:            printf("do..while"); break;
    case PTTEllipsis:           printf("..."); break;
    case PTTElement:            printf("."); break;
    case PTTEnumSpecifier:      printf("enum spec"); break;
    case PTTEqual:              printf("=="); break;
    case PTTFor:                printf("for"); break;
    case PTTFuncCall:           printf("function call"); break;
    case PTTFuncDef:            printf("function definition"); break;
    case PTTGreaterThan:        printf(">"); break;
    case PTTGreaterThanOrEqual: printf(">="); break;
    case PTTGoto:               printf("goto"); break;
    case PTTIf:                 printf("if"); break;
    case PTTInitialiser:        printf("initialiser"); break;
    case PTTLabel:              printf("label"); break;
    case PTTLessThan:           printf("<"); break;
    case PTTLessThanOrEqual:    printf("<="); break;
    case PTTLogicalAnd:         printf("&&"); break;
    case PTTLogicalOr:          printf("||"); break;
    case PTTModulus:            printf("%%"); break;
    case PTTModulusAssign:      printf("%%="); break;
    case PTTMultiply:           printf("multiply"); break;
    case PTTMultiplyAssign:     printf("*="); break;
    case PTTNegate:             printf("negate"); break;
    case PTTNot:                printf("!"); break;
    case PTTNotEqual:           printf("!="); break;
    case PTTPointer:            printf("pointer"); break;
    case PTTPostDec:            printf("postinc"); break;
    case PTTPostInc:            printf("postdec"); break;
    case PTTPreDec:             printf("predec"); break;
    case PTTPreInc:             printf("preinc"); break;
    case PTTReturn:             printf("return"); break;
    case PTTSequence:           printf("sequence"); break;
    case PTTShiftLeft:          printf("<<"); break;
    case PTTShiftLeftAssign:    printf("<<="); break;
    case PTTShiftRight:         printf(">>"); break;
    case PTTShiftRightAssign:   printf(">>="); break;
    case PTTSizeof:             printf("sizeof"); break;
    case PTTSpecifierQualifierList: printf("specifier qualifier list"); break;
    case PTTStructDeclaration:  printf("struct declaration"); break;
    case PTTStructDeclarator:   printf("struct declarator"); break;
    case PTTSubtract:           printf("-"); break;
    case PTTSubtractAssign:     printf("-="); break;
    case PTTSwitch:             printf("switch"); break;
    case PTTTernaryOp:          printf("?:"); break;
    case PTTTypeArrayDeclarator: printf("type - array declarator"); break;
    case PTTTypeAuto:           printf("type - auto"); break;
    case PTTTypeBool:           printf("type - bool"); break;
    case PTTTypeChar:           printf("type - char"); break;
    case PTTTypeComplex:        printf("type - complex"); break;
    case PTTTypeDouble:         printf("type - double"); break;
    case PTTTypeExtern:         printf("type - extern"); break;
    case PTTTypeFunction:       printf("type - function"); break;
    case PTTTypeImaginary:      printf("type - imaginary"); break;
    case PTTTypeInline:         printf("type - inline"); break;
    case PTTTypeInt:            printf("type - int"); break;
    case PTTTypeFloat:          printf("type - float"); break;
    case PTTTypeLong:           printf("type - long"); break;
    case PTTTypePointer:        printf("type - pointer"); break;
    case PTTTypeRegister:       printf("type - register"); break;
    case PTTTypeShort:          printf("type - short"); break;
    case PTTTypeSigned:         printf("type - signed"); break;
    case PTTTypeStatic:         printf("type - static"); break;
    case PTTTypeStruct:         printf("type - struct"); break;
    case PTTTypeTypedef:        printf("type - typedef"); break;
    case PTTTypeUnion:          printf("type - union"); break;
    case PTTTypeUnsigned:       printf("type - unsigned"); break;
    case PTTTypeVoid:           printf("type - void"); break;
    case PTTUnaryPlus:          printf("unary plus"); break;
    case PTTValue:              printf("value"); break;
    case PTTWhile:              printf("while"); break;


    default:
        printf("unknown");
    }
    printf("\n");

    // descend
    if (Left != NULL)
        Left->Dump(Level+1);

    if (Right != NULL)
        Right->Dump(Level+1);
}
